package com.mindata.blockchain.core.manager;

import com.mindata.blockchain.block.Block;
import com.mindata.blockchain.block.RLP.BlockB;
import com.mindata.blockchain.block.db.DbStore;
import com.mindata.blockchain.common.Constants;
import com.mindata.blockchain.common.util.ByteUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author wuweifeng wrote on 2018/3/13.
 */
@Service
public class DbBlockManager {
    @Resource
    private DbStore dbStore;


    public void put(String key, String value) {
        dbStore.put(key.getBytes(), value.getBytes());
    }
//
    public byte[] get(String key) {
        return dbStore.get(key.getBytes());
    }

    public void put(byte[] key, byte[] value) {
        dbStore.put(key, value);
    }

    public byte[] get(byte[] key) {
        return dbStore.get(key);
    }

    /**
     * 查找第一个区块
     *
     * @return 第一个Block
     */
    public Block getFirstBlock() {
        byte[] firstBlockHash = get(Constants.KEY_FIRST_BLOCK);
        if (ByteUtil.isNullOrZeroArray(firstBlockHash)) {
            return null;
        }
        return getBlockByHash(firstBlockHash);
    }

    /**
     * 获取最后一个区块信息
     *
     * @return 最后一个区块
     */
    public Block getLastBlock() {
        byte[] lastBlockHash = get(Constants.KEY_LAST_BLOCK);
        if (ByteUtil.isNullOrZeroArray(lastBlockHash)) {
            return null;
        }
        return getBlockByHash(lastBlockHash);
    }

    /**
     * 获取最后一个区块的hash
     *
     * @return hash
     */
    public String getLastBlockHash() {
        Block block = getLastBlock();
        if (block != null) {
            return block.getHash();
        }
        return null;
    }

    /**
     * 获取最后一个block的number
     *
     * @return number
     */
    public int getLastBlockNumber() {
        Block block = getLastBlock();
        if (block != null) {
            return block.getBlockHeader().getNumber();
        }
        return 0;
    }

    /**
     * 获取某一个block的下一个Block
     *
     * @param block block
     * @return block
     */
    public Block getNextBlock(Block block) {
        if (block == null) {
            return getFirstBlock();
        }
        byte[] nextHash = get(Constants.KEY_BLOCK_NEXT_PREFIX + block.getHash());
        if (ByteUtil.isNullOrZeroArray(nextHash)) {
            return null;
        }
        return getBlockByHash(nextHash);
    }

    public Block getNextBlockByHash(String hash) {
        if (hash == null) {
            return getFirstBlock();
        }
        byte[] nextHash = get(Constants.KEY_BLOCK_NEXT_PREFIX + hash);
        if (ByteUtil.isNullOrZeroArray(nextHash)) {
            return null;
        }
        return getBlockByHash(nextHash);
    }

    public Block getBlockByHash(byte[] hash) {
        byte[] blockJson = get(hash);
        Block block=new BlockB(blockJson).convertToBlock();
        return block;
    }

    public Block getBlockByHash(String hash) {
        byte[] blockJson = get(hash.getBytes());
        Block block=new BlockB(blockJson).convertToBlock();
        return block;
    }

}
